Welcome to my notebook covering the use of the tidycensus R package for extracting and evaluating census data in the state of Oregon. We are interested in uncovering the percentages of the population with graduate level degrees at a county level.

Start by importing the list of libraries that will assist us in connecting with the Census Bureau’s APIs and visualizing the desired data.
library(tidycensus) # connect with the census bureau API
library(tidyverse) # data wrangling
library(mapview) # spatial data visualizer
library(plotly) # graph / chart visualizer
library(ggiraph) # graph / chart visualizer
library(ggplot2)
library(DT)
library(scales)
library(sf)
We will use the get_acs() function from tidycensus package to pull data from the census bureau. The function defaults to the 2017-2021 5-year ACS dataset. Which is necessary for us, since there are a list of counties in Oregon with a population of less than 65,000.
# Data objects needed
or_grads <- get_acs(
  geography = "county",
  variables = "DP02_0066P", 
  state = "OR",
  year = 2021,
)

or_grads_table <- or_grads %>%
  separate(NAME, into = c("county", "state"), sep = ", ") %>%
  arrange(-estimate) %>%
  select(county, estimate, moe)
We have our results in a table and we can filter through to see all counties with their percent of population with graduate degrees. Lets use the datatable() function from the DT library to provide a bit more interactivity for previewing the results.
# function from the DT library
datatable(or_grads_table)
Top 3 counties –

  • Benton
  • Multnomah
  • Washington

Bottom 3 counties –

  • Malheur
  • Gilliam
  • Morrow
or_plot <- ggplot(or_grads_table, aes(x = estimate,
                                      y = reorder(county, estimate))) + 
  geom_point(color="navy", size = 3) +
  scale_x_continuous(labels = function(x) paste0(x, '%')) +
  scale_y_discrete(labels = function(x) str_remove(x, " County")) +
  labs(title = "% Population with graduate degrees, 2017-2021 ACS",
       subtitle = "Counties in Oregon",
       caption = "Data acquired with R and tidycensus",
       x = "ACS estimate",
       y = "") +
  theme_minimal(base_size = 12)
  
or_plot

or_plot_errorbar <- ggplot(or_grads, aes(x = estimate, y = reorder(NAME, estimate))) +
  geom_errorbar(aes(xmin = estimate - moe, xmax = estimate + moe), 
                width = 0.5, linewidth = 0.5) +
  geom_point(color = "gold", size = 3) +
  scale_x_continuous(labels = function(x) paste0(x, '%')) +
  scale_y_discrete(labels = function(x) str_remove(x, " County, Oregon|, Oregon")) +
  labs(title = "% Population with graduate degrees, 2017-2021 ACS",
       subtitle = "Counties in Oregon",
       caption = "Data acquired with R and tidycensus. Error bars represent margin of error around estimates.",
       "ACS estimate",
      y = "",
      x = "Percentage") +
  theme_minimal(base_size = 12)
  
or_plot_errorbar

ggplotly(or_plot_errorbar, tooltip = "x")
NA
# Data objects needed
or_grads_geom <- get_acs(
  geography = "county",
  variables = "DP02_0066P", 
  state = "OR",
  year = 2021,
  geometry = TRUE
)



ggplot() + # use ggplot to create the plot.
    geom_sf(data = or_grads_geom, # use geom_sf to plot the polyline geometry.
            aes(fill = as.factor(estimate)),
            linewidth = 1) + # color based on year.
    scale_color_discrete(name = "estimate") + # set color scale
    coord_sf(datum = NA) + # put geometries on the same coordinate reference system
    theme_void()
LS0tDQp0aXRsZTogIkhpZ2hlciBlZHVjYXRpb24gJSBpbiBPcmVnb24gLSBBbGlzIHZvbGF0IHByb3ByaWlzIg0Kb3V0cHV0OiBodG1sX25vdGVib29rDQotLS0NCiMjIyMgV2VsY29tZSB0byBteSBub3RlYm9vayBjb3ZlcmluZyB0aGUgdXNlIG9mIHRoZSB0aWR5Y2Vuc3VzIFIgcGFja2FnZSBmb3IgZXh0cmFjdGluZyBhbmQgZXZhbHVhdGluZyBjZW5zdXMgZGF0YSBpbiB0aGUgc3RhdGUgb2YgT3JlZ29uLiBXZSBhcmUgaW50ZXJlc3RlZCBpbiB1bmNvdmVyaW5nIHRoZSBwZXJjZW50YWdlcyBvZiB0aGUgcG9wdWxhdGlvbiB3aXRoIGdyYWR1YXRlIGxldmVsIGRlZ3JlZXMgYXQgYSBjb3VudHkgbGV2ZWwuIA0KDQojIyMjIyBTdGFydCBieSBpbXBvcnRpbmcgdGhlIGxpc3Qgb2YgbGlicmFyaWVzIHRoYXQgd2lsbCBhc3Npc3QgdXMgaW4gY29ubmVjdGluZyB3aXRoIHRoZSBDZW5zdXMgQnVyZWF1J3MgQVBJcyBhbmQgdmlzdWFsaXppbmcgdGhlIGRlc2lyZWQgZGF0YS4gDQpgYGB7Y3NzLCBlY2hvPUZBTFNFfQ0KcCB7DQogIG1hcmdpbi1ib3R0b206IDBweDsNCn0NCmBgYA0KYGBge3IgbWVzc2FnZSA9IEZBTFNFLCB3YXJuaW5nID0gRkFMU0V9DQpsaWJyYXJ5KHRpZHljZW5zdXMpICMgY29ubmVjdCB3aXRoIHRoZSBjZW5zdXMgYnVyZWF1IEFQSQ0KbGlicmFyeSh0aWR5dmVyc2UpICMgZGF0YSB3cmFuZ2xpbmcNCmxpYnJhcnkobWFwdmlldykgIyBzcGF0aWFsIGRhdGEgdmlzdWFsaXplcg0KbGlicmFyeShwbG90bHkpICMgZ3JhcGggLyBjaGFydCB2aXN1YWxpemVyDQpsaWJyYXJ5KGdnaXJhcGgpICMgZ3JhcGggLyBjaGFydCB2aXN1YWxpemVyDQpsaWJyYXJ5KGdncGxvdDIpDQpsaWJyYXJ5KERUKQ0KbGlicmFyeShzY2FsZXMpDQpsaWJyYXJ5KHNmKQ0KYGBgDQojIyMjIyBXZSB3aWxsIHVzZSB0aGUgZ2V0X2FjcygpIGZ1bmN0aW9uIGZyb20gdGlkeWNlbnN1cyBwYWNrYWdlIHRvIHB1bGwgZGF0YSBmcm9tIHRoZSBjZW5zdXMgYnVyZWF1LiBUaGUgZnVuY3Rpb24gZGVmYXVsdHMgdG8gdGhlIDIwMTctMjAyMSA1LXllYXIgQUNTIGRhdGFzZXQuIFdoaWNoIGlzIG5lY2Vzc2FyeSBmb3IgdXMsIHNpbmNlIHRoZXJlIGFyZSBhIGxpc3Qgb2YgY291bnRpZXMgaW4gT3JlZ29uIHdpdGggYSBwb3B1bGF0aW9uIG9mIGxlc3MgdGhhbiA2NSwwMDAuIA0KYGBge3IgbWVzc2FnZSA9IEZBTFNFLCB3YXJuaW5nID0gRkFMU0V9DQojIERhdGEgb2JqZWN0cyBuZWVkZWQNCm9yX2dyYWRzIDwtIGdldF9hY3MoDQogIGdlb2dyYXBoeSA9ICJjb3VudHkiLA0KICB2YXJpYWJsZXMgPSAiRFAwMl8wMDY2UCIsIA0KICBzdGF0ZSA9ICJPUiIsDQogIHllYXIgPSAyMDIxLA0KKQ0KDQpvcl9ncmFkc190YWJsZSA8LSBvcl9ncmFkcyAlPiUNCiAgc2VwYXJhdGUoTkFNRSwgaW50byA9IGMoImNvdW50eSIsICJzdGF0ZSIpLCBzZXAgPSAiLCAiKSAlPiUNCiAgYXJyYW5nZSgtZXN0aW1hdGUpICU+JQ0KICBzZWxlY3QoY291bnR5LCBlc3RpbWF0ZSwgbW9lKQ0KYGBgDQojIyMjIyBXZSBoYXZlIG91ciByZXN1bHRzIGluIGEgdGFibGUgYW5kIHdlIGNhbiBmaWx0ZXIgdGhyb3VnaCB0byBzZWUgYWxsIGNvdW50aWVzIHdpdGggdGhlaXIgcGVyY2VudCBvZiBwb3B1bGF0aW9uIHdpdGggZ3JhZHVhdGUgZGVncmVlcy4gTGV0cyB1c2UgdGhlIGRhdGF0YWJsZSgpIGZ1bmN0aW9uIGZyb20gdGhlIERUIGxpYnJhcnkgdG8gcHJvdmlkZSBhIGJpdCBtb3JlIGludGVyYWN0aXZpdHkgZm9yIHByZXZpZXdpbmcgdGhlIHJlc3VsdHMuDQpgYGB7cn0NCiMgZnVuY3Rpb24gZnJvbSB0aGUgRFQgbGlicmFyeQ0KZGF0YXRhYmxlKG9yX2dyYWRzX3RhYmxlKQ0KYGBgDQojIyMjIyBUb3AgMyBjb3VudGllcyAtLQ0KPGhyIC8+DQoqIEJlbnRvbg0KKiBNdWx0bm9tYWgNCiogV2FzaGluZ3Rvbg0KDQo8aHIgLz4NCg0KIyMjIyMgQm90dG9tIDMgY291bnRpZXMgLS0NCjxociAvPg0KKiBNYWxoZXVyDQoqIEdpbGxpYW0NCiogTW9ycm93DQpgYGB7ciBmaWcuaGVpZ2h0PTZ9DQpvcl9wbG90IDwtIGdncGxvdChvcl9ncmFkc190YWJsZSwgYWVzKHggPSBlc3RpbWF0ZSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeSA9IHJlb3JkZXIoY291bnR5LCBlc3RpbWF0ZSkpKSArIA0KICBnZW9tX3BvaW50KGNvbG9yPSJuYXZ5Iiwgc2l6ZSA9IDMpICsNCiAgc2NhbGVfeF9jb250aW51b3VzKGxhYmVscyA9IGZ1bmN0aW9uKHgpIHBhc3RlMCh4LCAnJScpKSArDQogIHNjYWxlX3lfZGlzY3JldGUobGFiZWxzID0gZnVuY3Rpb24oeCkgc3RyX3JlbW92ZSh4LCAiIENvdW50eSIpKSArDQogIGxhYnModGl0bGUgPSAiJSBQb3B1bGF0aW9uIHdpdGggZ3JhZHVhdGUgZGVncmVlcywgMjAxNy0yMDIxIEFDUyIsDQogICAgICAgc3VidGl0bGUgPSAiQ291bnRpZXMgaW4gT3JlZ29uIiwNCiAgICAgICBjYXB0aW9uID0gIkRhdGEgYWNxdWlyZWQgd2l0aCBSIGFuZCB0aWR5Y2Vuc3VzIiwNCiAgICAgICB4ID0gIkFDUyBlc3RpbWF0ZSIsDQogICAgICAgeSA9ICIiKSArDQogIHRoZW1lX21pbmltYWwoYmFzZV9zaXplID0gMTIpDQogIA0Kb3JfcGxvdA0KYGBgDQpgYGB7ciBmaWcuaGVpZ2h0PTZ9DQpvcl9wbG90X2Vycm9yYmFyIDwtIGdncGxvdChvcl9ncmFkcywgYWVzKHggPSBlc3RpbWF0ZSwgeSA9IHJlb3JkZXIoTkFNRSwgZXN0aW1hdGUpKSkgKw0KICBnZW9tX2Vycm9yYmFyKGFlcyh4bWluID0gZXN0aW1hdGUgLSBtb2UsIHhtYXggPSBlc3RpbWF0ZSArIG1vZSksIA0KICAgICAgICAgICAgICAgIHdpZHRoID0gMC41LCBsaW5ld2lkdGggPSAwLjUpICsNCiAgZ2VvbV9wb2ludChjb2xvciA9ICJnb2xkIiwgc2l6ZSA9IDMpICsNCiAgc2NhbGVfeF9jb250aW51b3VzKGxhYmVscyA9IGZ1bmN0aW9uKHgpIHBhc3RlMCh4LCAnJScpKSArDQogIHNjYWxlX3lfZGlzY3JldGUobGFiZWxzID0gZnVuY3Rpb24oeCkgc3RyX3JlbW92ZSh4LCAiIENvdW50eSwgT3JlZ29ufCwgT3JlZ29uIikpICsNCiAgbGFicyh0aXRsZSA9ICIlIFBvcHVsYXRpb24gd2l0aCBncmFkdWF0ZSBkZWdyZWVzLCAyMDE3LTIwMjEgQUNTIiwNCiAgICAgICBzdWJ0aXRsZSA9ICJDb3VudGllcyBpbiBPcmVnb24iLA0KICAgICAgIGNhcHRpb24gPSAiRGF0YSBhY3F1aXJlZCB3aXRoIFIgYW5kIHRpZHljZW5zdXMuIEVycm9yIGJhcnMgcmVwcmVzZW50IG1hcmdpbiBvZiBlcnJvciBhcm91bmQgZXN0aW1hdGVzLiIsDQogICAgICAgIkFDUyBlc3RpbWF0ZSIsDQogICAgICB5ID0gIiIsDQogICAgICB4ID0gIlBlcmNlbnRhZ2UiKSArDQogIHRoZW1lX21pbmltYWwoYmFzZV9zaXplID0gMTIpDQogIA0Kb3JfcGxvdF9lcnJvcmJhcg0KYGBgDQpgYGB7ciBmaWcuaGVpZ2h0PTYsIGZpZy53aWR0aD05LjV9DQpnZ3Bsb3RseShvcl9wbG90X2Vycm9yYmFyLCB0b29sdGlwID0gIngiKQ0KDQpgYGANCg0KYGBge3IgIG1lc3NhZ2UgPSBGQUxTRSwgd2FybmluZyA9IEZBTFNFfQ0KIyBEYXRhIG9iamVjdHMgbmVlZGVkDQpvcl9ncmFkc19nZW9tIDwtIGdldF9hY3MoDQogIGdlb2dyYXBoeSA9ICJjb3VudHkiLA0KICB2YXJpYWJsZXMgPSAiRFAwMl8wMDY2UCIsIA0KICBzdGF0ZSA9ICJPUiIsDQogIHllYXIgPSAyMDIxLA0KICBnZW9tZXRyeSA9IFRSVUUNCikNCg0KDQoNCmdncGxvdCgpICsgIyB1c2UgZ2dwbG90IHRvIGNyZWF0ZSB0aGUgcGxvdC4NCiAgICBnZW9tX3NmKGRhdGEgPSBvcl9ncmFkc19nZW9tLCAjIHVzZSBnZW9tX3NmIHRvIHBsb3QgdGhlIHBvbHlsaW5lIGdlb21ldHJ5Lg0KICAgICAgICAgICAgYWVzKGZpbGwgPSBhcy5mYWN0b3IoZXN0aW1hdGUpKSwNCiAgICAgICAgICAgIGxpbmV3aWR0aCA9IDEpICsgIyBjb2xvciBiYXNlZCBvbiB5ZWFyLg0KICAgIHNjYWxlX2NvbG9yX2Rpc2NyZXRlKG5hbWUgPSAiZXN0aW1hdGUiKSArICMgc2V0IGNvbG9yIHNjYWxlDQogICAgY29vcmRfc2YoZGF0dW0gPSBOQSkgKyAjIHB1dCBnZW9tZXRyaWVzIG9uIHRoZSBzYW1lIGNvb3JkaW5hdGUgcmVmZXJlbmNlIHN5c3RlbQ0KICAgIHRoZW1lX3ZvaWQoKQ0KYGBg